package 临时工具.粮仓.APDU;


import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Data
public class XMLBuilder {
    private static final Pattern pattern = Pattern.compile("^(.*)\\[(\\d+)]$");
    private final Document doc;
    private final Element root;
    private String rootName;

    public XMLBuilder(String rootName) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        doc = builder.newDocument();
        root = doc.createElement(rootName);
        doc.appendChild(root);
        doc.setXmlStandalone(true);
        this.rootName=rootName;
    }


    public String build() throws Exception {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");

        StringWriter writer = new StringWriter();
        transformer.transform(new DOMSource(doc), new StreamResult(writer));
        return writer.toString();
    }


    public String get(String path) {
        String[] parts = path.split("\\.");
        Element parent = this.root;
        for (String part : parts) {
            Matcher matcher = pattern.matcher(part);
            if (matcher.matches()) {
                String nodeName = matcher.group(1);
                int index = Integer.parseInt(matcher.group(2));
                NodeList children = parent.getElementsByTagName(nodeName);
                if (children.getLength() <= index) {
                    return null;
                }
                parent=(Element) children.item(index);
            }else{
                NodeList children = parent.getElementsByTagName(part);
                if (children.getLength() == 0) {
                    return null;
                }
                parent=(Element) children.item(0);
            }
        }
        return parent.getTextContent();
    }
    public XMLBuilder add(String name){
        return add(name,null);
    }
    public XMLBuilder add(String name, String value) {
        String[] parts = name.split("\\.");

        Element parent = this.root;
        for (String  part: parts) {
            Matcher matcher = pattern.matcher(part);
            if (matcher.matches()) {
                String nodeName = matcher.group(1);
                int index = Integer.parseInt(matcher.group(2));


                NodeList elementsByTagName = parent.getElementsByTagName(nodeName);
                if (elementsByTagName.getLength() <= index) {
                    Element element =null;
                    for (int i=elementsByTagName.getLength(); i<=index; i++){
                        element=doc.createElement(nodeName);
                        parent.appendChild(element);

                    }
                    parent=element;
                }else{
                    parent=(Element) elementsByTagName.item(index);
                }

            } else {
                NodeList elementsByTagName = parent.getElementsByTagName(part);
                if (elementsByTagName.getLength() == 0) {
                    Element element = doc.createElement(part);
                    parent.appendChild(element);
                    parent=element;
                }else{
                    parent=(Element) elementsByTagName.item(0);
                }
            }


        }
        parent.setTextContent(StringUtils.isBlank(value)?"":value);
        return this;
    }
    public static void main(String[] args) throws Exception {

        XMLBuilder xmlBuilder = new XMLBuilder("project");
        String build = xmlBuilder
                .add("dependencies")
                .add("dependencies.dependency[0].groupId", "hutool")
                .add("dependencies.dependency[0].artifactId", "hutool-all")
                .add("dependencies.dependency[0].version", "5.8.11")
                .add("dependencies.dependency[2].groupId", "junit")
                .add("dependencies.dependency[2].artifactId", "junit")
                .add("dependencies.dependency[2].version", "4.11")
                .add("dependencies.dependency[2].scope", "test")
                .build();
        System.out.println(build);
        System.out.println(xmlBuilder.get("dependencies.dependency[2].version"));
    }
    public static void parse(String str){

        Matcher matcher = pattern.matcher(str);
        if (matcher.matches()) {
            String name = matcher.group(1);
            int index = Integer.parseInt(matcher.group(2));
            System.out.println(name+":"+index);
        } else {
            System.out.println(str);
        }
    }
}
